package fr.inria.phoenix.scenario.bwsnfirefighting.framework.distributed.alarmmanager;

import java.util.HashMap;

import fr.inria.diagen.core.ServiceConfiguration;
import fr.inria.diagen.core.exception.DiaGenException;
import fr.inria.diagen.core.exception.InvocationException;
import fr.inria.diagen.core.network.RemoteServiceInfo;
import fr.inria.diagen.core.service.local.Service;

import fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel;

import fr.inria.diagen.core.service.proxy.Proxy;
import fr.inria.diagen.core.module.event.IEventNotifyListener;
import fr.inria.diagen.core.service.filter.service.ServiceFilter;
import fr.inria.diagen.core.server.local.EventSubscription;
import fr.inria.diagen.core.exception.InvocationException;

/**
 * Controller which start the actions on the Light and Sound devices when something arise
 *
 * @[101,0]
 * controller AlarmManager{
 * context BuildingAlertDetection;
 * action Activate on Sound;
 * action Activate on Light;
 * }
 */
public abstract class AlarmManager extends Service implements IEventNotifyListener {
  /**
     * @param serviceConfiguration
     */
    public AlarmManager(ServiceConfiguration serviceConfiguration ) {
      super("AlarmManager", serviceConfiguration, GeneratedFramework.getInstance());
    }

    protected final void _postInitialize() {
        subscribeBuildingAlertDetection();

        postInitialize();
    }

    protected void postInitialize() {}


    public void notifyReceived(RemoteServiceInfo servicePublisher, String eventName, Object arg) {
        try {
          if (eventName.equals("BuildingAlertDetection") && servicePublisher.getClassName().equals("BuildingAlertDetection")) {
            onNewBuildingAlertDetection ((fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel) arg);          }

        } catch (Exception e) {
              e.printStackTrace();
        }
    }

    public abstract void onNewBuildingAlertDetection(fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel newBuildingAlertDetectionValue);
    
    
    private final void subscribeBuildingAlertDetection() {
      getServer().subscribe(new EventSubscription(getBuildingAlertDetectionRSI(), getServiceInfo(), "BuildingAlertDetection"), 3600);
    }

    private RemoteServiceInfo getBuildingAlertDetectionRSI() {
      ServiceFilter filter = new ServiceFilter("BuildingAlertDetection");
      RemoteServiceInfo[] rsis = getServicesInfo(getServer(), filter);
      return rsis[0];
    }
    
    protected final fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel getBuildingAlertDetection() throws InvocationException {
      return (fr.inria.phoenix.scenario.bwsnfirefighting.framework.datatype.DangerLevel) getProcessor().command(getBuildingAlertDetectionRSI(), "getBuildingAlertDetection");
    }


    protected final SoundComposite discover(SoundServiceFilter filter) {
      RemoteServiceInfo[] rsis = getServicesInfo(getServer(), filter);
      SoundProxy[] proxies = new SoundProxy[rsis.length];
      for (int i = 0; i < rsis.length; i++) {
        proxies[i] = new SoundProxy(getProcessor(), rsis[i]);
      }
      return new SoundComposite(proxies, this);
    }
    
    protected final SoundComposite allSounds() {
        return discover(new SoundServiceFilter());
    }
    
    protected final SoundServiceFilter soundsWhere() {
        return new SoundServiceFilter();
    }

    protected final LightComposite discover(LightServiceFilter filter) {
      RemoteServiceInfo[] rsis = getServicesInfo(getServer(), filter);
      LightProxy[] proxies = new LightProxy[rsis.length];
      for (int i = 0; i < rsis.length; i++) {
        proxies[i] = new LightProxy(getProcessor(), rsis[i]);
      }
      return new LightComposite(proxies, this);
    }
    
    protected final LightComposite allLights() {
        return discover(new LightServiceFilter());
    }
    
    protected final LightServiceFilter lightsWhere() {
        return new LightServiceFilter();
    }

} 